#pragma once

#include "lib/httplib.h"
#include "lib/easylog.h"
#include "util.hh"

namespace atm_server
{
class server
{
public:
    using business = std::function<void(const httplib::Request&, httplib::Response&)>;

    static server& instance(int port)
    {
        static server svr(port);
        return svr;
    }

private:
    server(int port)
        : _ip("0.0.0.0")
        , _port(port)
    {}

    server(const server&) = delete;
    server& operator=(const server&) = delete;

public:
    void regist(business balance, business deposit, business withdraw, business transfer)
    {
        _balance = balance;
        _deposit = deposit;
        _withdraw = withdraw;
        _transfer = transfer;
    }

    void run()
    {
        if (!_balance)  throw except("balance business is not callable");
        if (!_deposit)  throw except("deposit business is not callable");
        if (!_withdraw) throw except("withdraw business is not callable");
        if (!_transfer) throw except("transfer business is not callable");

        _svr.Post("/balance", _balance);
        _svr.Post("/deposit", _deposit);
        _svr.Post("/withdraw", _withdraw);
        _svr.Post("/transfer", _transfer);

        easylog::info("http server started on {}", _port);

        if (!_svr.listen(_ip, _port))
            easylog::error("http server start failed on {}:{}", _ip, _port);
    }

private:
    std::string _ip;
    uint16_t _port;
    httplib::Server _svr;

    business _balance;
    business _deposit;
    business _withdraw;
    business _transfer;
};
}
